/**
 * Copyright (C) 2011, Karsten Priegnitz
 *
 * Permission to use, copy, modify, and distribute this piece of software
 * for any purpose with or without fee is hereby granted, provided that
 * the above copyright notice and this permission notice appear in the
 * source code of all copies.
 *
 * It would be appreciated if you mention the author in your change log,
 * contributors list or the like.
 *
 * @author: Karsten Priegnitz
 * @see: http://code.google.com/p/android-change-log/
 */
package apptoko.com.view;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.preference.PreferenceManager;
import android.util.Log;
import android.webkit.WebView;
import apptoko.com.model.AppStoreVnAboutUpdateData;
import apptoko.com.model.ApptokoUpdateData;
import apptoko.com.util.Constants;

import apptoko.com.R;
;

public class ChangeLog {

	private final Activity context;
	private String lastVersion, thisVersion;
	private static String title="";
	// this is the key for storing the version name in SharedPreferences
	private static final String VERSION_KEY = "PREFS_VERSION_KEY";

	private static final String NO_VERSION = "";

	/**
	 * Constructor
	 * 
	 * Retrieves the version names and stores the new version name in
	 * SharedPreferences
	 * 
	 * @param context
	 */
	public ChangeLog(Activity context,String title) {
		this(context, context.getSharedPreferences(Constants.SHARED_NAME, Activity.MODE_PRIVATE),title);
	}

	/**
	 * Constructor
	 * 
	 * Retrieves the version names and stores the new version name in
	 * SharedPreferences
	 * 
	 * @param context
	 * @param sp
	 *            the shared preferences to store the last version name into
	 */
	public ChangeLog(Activity context, SharedPreferences sp,String title) {
		this.context = context;
		this.title=title;
		// get version numbers
		this.lastVersion = sp.getString(VERSION_KEY, NO_VERSION);
		Log.d(TAG, "lastVersion: " + lastVersion);
		try {
			this.thisVersion = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0).versionName;
		} catch (NameNotFoundException e) {
			this.thisVersion = NO_VERSION;
			Log.e(TAG, "could not get version name from manifest!");
			e.printStackTrace();
		}
		Log.d(TAG, "appVersion: " + this.thisVersion);
	}

	/**
	 * @return The version name of the last installation of this app (as
	 *         described in the former manifest). This will be the same as
	 *         returned by <code>getThisVersion()</code> the second time this
	 *         version of the app is launched (more precisely: the second time
	 *         ChangeLog is instantiated).
	 * @see AndroidManifest.xml#android:versionName
	 */
	public String getLastVersion() {
		return this.lastVersion;
	}

	/**
	 * @return The version name of this app as described in the manifest.
	 * @see AndroidManifest.xml#android:versionName
	 */
	public String getThisVersion() {
		return this.thisVersion;
	}

	/**
	 * @return <code>true</code> if this version of your app is started the
	 *         first time
	 */
	public boolean firstRun() {
		return !this.lastVersion.equals(this.thisVersion);
	}

	/**
	 * @return <code>true</code> if your app including ChangeLog is started the
	 *         first time ever. Also <code>true</code> if your app was
	 *         deinstalled and installed again.
	 */
	public boolean firstRunEver() {
		return NO_VERSION.equals(this.lastVersion);
	}

	/**
	 * @return An AlertDialog displaying the changes since the previous
	 *         installed version of your app (what's new). But when this is the
	 *         first run of your app including ChangeLog then the full log
	 *         dialog is show.
	 */
	public AlertDialog getLogDialog(ApptokoUpdateData data,AppStoreVnAboutUpdateData data2) {
		return this.getDialog(data,data2, this.firstRunEver());
	}

	/**
	 * @return an AlertDialog with a full change log displayed
	 */
	public AlertDialog getFullLogDialog(ApptokoUpdateData data,AppStoreVnAboutUpdateData data2) {
		return this.getDialog(data,data2, true);
	}

	private AlertDialog getDialog(final ApptokoUpdateData data,final AppStoreVnAboutUpdateData data2, boolean full) {
		WebView wv = new WebView(this.context);
		wv.setBackgroundColor(Color.WHITE); // transparent
		// wv.getSettings().setDefaultTextEncodingName("utf-8");
		wv.loadDataWithBaseURL(null, this.getLog(data==null?data2.getMessContent():data.getMessContent(), full), "text/html", "UTF-8",
				null);

		AlertDialog.Builder builder = new AlertDialog.Builder(this.context);
		builder.setTitle(full?title:
				context.getResources().getString(R.string.changelog_title))
				.setView(wv)
				.setCancelable(false)
				// OK button
				.setPositiveButton(
						context.getResources().getString(
								R.string.changelog_ok_button),
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int which) {
								//updateVersionInPreferences();
								context.setResult(Activity.RESULT_OK);
								context.finish();
								dialog.dismiss();
							}
						})
				.setNegativeButton(
						context.getResources().getString(
								R.string.changelog_cancel_button),
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								// TODO Auto-generated method stub
								context.setResult(Activity.RESULT_CANCELED);
								context.finish();
								dialog.dismiss();
							}
						});

		if (!full) {
			// "more ..." button
			builder.setNegativeButton(R.string.changelog_show_full,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							getFullLogDialog(data,data2).show();
						}
					});
		}
		
		return builder.create();
	}

	private void updateVersionInPreferences() {
		// save new version number to preferences
		SharedPreferences sp = context.getSharedPreferences(Constants.SHARED_NAME, Activity.MODE_PRIVATE);
		SharedPreferences.Editor editor = sp.edit();
		editor.putString(VERSION_KEY, thisVersion);
		// // on SDK-Versions > 9 you should use this:
		// if(Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
		// editor.commit();
		// } else {
		// editor.apply();
		// }
		editor.commit();
	}

	/**
	 * @return HTML displaying the changes since the previous installed version
	 *         of your app (what's new)
	 */
	public String getLog(ApptokoUpdateData data,AppStoreVnAboutUpdateData data2) {
		if(data==null){
			return data2.getMessContent();
		}else{
			return data.getMessContent();
		}
	}

	/**
	 * @return HTML which displays full change log
	 */
	public String getFullLog(ApptokoUpdateData data,AppStoreVnAboutUpdateData data2) {
		if(data==null){
			return data2.getMessContent();
		}else{
			return data.getMessContent();
		}
	}

	/** modes for HTML-Lists (bullet, numbered) */
	private enum Listmode {
		NONE, ORDERED, UNORDERED,
	};

	private Listmode listMode = Listmode.NONE;
	private StringBuffer sb = null;
	private static final String EOCL = "END_OF_CHANGE_LOG";

	private String getLog(String msg, boolean full) {
		// read changelog.txt file
		return msg;
//		sb = new StringBuffer();
//		try {
//			InputStream ins = context.getResources().openRawResource(
//					R.raw.changelog);
//			BufferedReader br = new BufferedReader(new InputStreamReader(ins));
//
//			String line = null;
//			boolean advanceToEOVS = false; // if true: ignore further version
//											// sections
//			while ((line = br.readLine()) != null) {
//				line = line.trim();
//				char marker = line.length() > 0 ? line.charAt(0) : 0;
//				if (marker == '$') {
//					// begin of a version section
//					this.closeList();
//					String version = line.substring(1).trim();
//					// stop output?
//					if (!full) {
//						if (this.lastVersion.equals(version)) {
//							advanceToEOVS = true;
//						} else if (version.equals(EOCL)) {
//							advanceToEOVS = false;
//						}
//					}
//				} else if (!advanceToEOVS) {
//					switch (marker) {
//					case '%':
//						// line contains version title
//						this.closeList();
//						sb.append("<div class='title'>"
//								+ line.substring(1).trim() + "</div>\n");
//						break;
//					case '_':
//						// line contains version title
//						this.closeList();
//						sb.append("<div class='subtitle'>"
//								+ line.substring(1).trim() + "</div>\n");
//						break;
//					case '!':
//						// line contains free text
//						this.closeList();
//						sb.append("<div class='freetext'>"
//								+ line.substring(1).trim() + "</div>\n");
//						break;
//					case '#':
//						// line contains numbered list item
//						this.openList(Listmode.ORDERED);
//						sb.append("<li>" + line.substring(1).trim() + "</li>\n");
//						break;
//					case '*':
//						// line contains bullet list item
//						this.openList(Listmode.UNORDERED);
//						sb.append("<li>" + line.substring(1).trim() + "</li>\n");
//						break;
//					default:
//						// no special character: just use line as is
//						this.closeList();
//						sb.append(line + "\n");
//					}
//				}
//			}
//			this.closeList();
//			br.close();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//
//		return sb.toString();
	}

	private void openList(Listmode listMode) {
		if (this.listMode != listMode) {
			closeList();
			if (listMode == Listmode.ORDERED) {
				sb.append("<div class='list'><ol>\n");
			} else if (listMode == Listmode.UNORDERED) {
				sb.append("<div class='list'><ul>\n");
			}
			this.listMode = listMode;
		}
	}

	private void closeList() {
		if (this.listMode == Listmode.ORDERED) {
			sb.append("</ol></div>\n");
		} else if (this.listMode == Listmode.UNORDERED) {
			sb.append("</ul></div>\n");
		}
		this.listMode = Listmode.NONE;
	}

	private static final String TAG = "ChangeLog";

	/**
	 * manually set the last version name - for testing purposes only
	 * 
	 * @param lastVersion
	 */
	void setLastVersion(String lastVersion) {
		this.lastVersion = lastVersion;
	}
}
